package edu.put.sk.nrpp.ui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.net.Inet4Address;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import edu.put.sk.nrpp.ConnectionList;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.Math;

public class GraphicsPanel extends JPanel {
	/**
	 * 
	 * To jest piekło, którego by sobie nawet Dante nie potrafił wyobrazić.
	 * Nie zaglądać. Nie modyfikować. Nie kwestionować.
	 * 
	 */
	ImageIcon picture;
	Image img;
	RouterList routerList;
	ConnectionList connectionList;
	private static final long serialVersionUID = 1878660665594110393L;

	/**
	 * Create the panel.
	 */
	GraphicsRouter gr1;
	GraphicsRouter gr2;
	GraphicsRouter gr3;
	public int maxX=0;
	public int maxY=0;
	public int iteration=0;
	
	public ArrayList<Router> sortList(ArrayList<Router> toSort){
		int changes;
		for (int i=0;i<toSort.size();i++){
			changes=0;
			Router router = toSort.get(i);
			for (int j=i+1;j<toSort.size();j++){
				Router router2 = toSort.get(j);
				for (int k=0;k<router.numberOfNeighbors;k++){
					if (router2 == router.connections.get(k).getNeighbor(router)){
						if (changes==0){
							//System.out.println("zmiana");
							toSort.remove(router2);
							toSort.add(i+1, router2);
							changes=1;
							break;
						}
					}
				}
				if (changes==1){
					break;
				}
			}
		}
		return toSort;
	}
	
	public ArrayList<Router> sortSecondList(ArrayList<Router> toSort){
		int changes;
		for (int i=0;i<toSort.size();i++){
			changes=0;
			Router router = toSort.get(i);
			for (int j=i+1;j<toSort.size();j++){
				Router router2 = toSort.get(j);
				for (int k=0;k<router.numberOfNeighbors;k++){
					if (router2 == router.connections.get(k).getNeighbor(router)){
						if (changes==0){
							//System.out.println("zmiana");
							toSort.remove(router2);
							toSort.add(i+1, router2);
							changes=1;
							break;
						}
					}
				}
				if (changes==1){
					break;
				}
			}
		}
		return toSort;
	}
	
	ArrayList<Double> previousAngleFromList;
	ArrayList<Double> previousAngleToList;
	ArrayList<Double> currentAngleFromList;
	ArrayList<Double> currentAngleToList;
	ArrayList<Double> notUsedAngleFromList;
	ArrayList<Double> notUsedAngleToList;
	ArrayList<Router> secondTypeRouter;  
	ArrayList<Double> secondTypeAngleFromList = new ArrayList<Double>();
	ArrayList<Double> secondTypeAngleToList = new ArrayList<Double>();
	ArrayList<Integer> secondTypeNeighbors = new ArrayList<Integer>();
	ArrayList<Integer> secondTypeSum = new ArrayList<Integer>();
	
	public void sumNotUsedAngle2(){
		ArrayList<Double> newNotUsedAngleFromList = new ArrayList<Double>();
		ArrayList<Double> newNotUsedAngleToList = new ArrayList<Double>();
		if (this.notUsedAngleFromList.size()>0){
			Double min = this.notUsedAngleFromList.get(0);
			Double max = this.notUsedAngleToList.get(0);
			if (min < 0){
				min = 6.283185307+min;
			}
			if (max < 0){
				max = 6.283185307+max;
			}
			for (int i=1;i<this.notUsedAngleFromList.size();i++){
				if (this.notUsedAngleFromList.get(i)<0){
					this.notUsedAngleFromList.set(i, 6.283185307+notUsedAngleFromList.get(i));
				}
				if (this.notUsedAngleToList.get(i)<0){
					this.notUsedAngleToList.set(i, 6.283185307+notUsedAngleToList.get(i));
				}
				if ((max < notUsedAngleFromList.get(i)+0.00001)&&(max > notUsedAngleFromList.get(i)-0.00001)){
					max = notUsedAngleToList.get(i);
				}
				else{
					newNotUsedAngleFromList.add(min);
					newNotUsedAngleToList.add(max);
					min = notUsedAngleFromList.get(i);
					max = notUsedAngleToList.get(i);
				}
			}
			newNotUsedAngleFromList.add(min);
			newNotUsedAngleToList.add(max);
			if (newNotUsedAngleFromList.size()>1){
				Double k,j;
				k = newNotUsedAngleToList.get(newNotUsedAngleToList.size()-1);
				j = newNotUsedAngleFromList.get(0);
				if ((k<j+0.00001)&&(k>j-0.00001)){
					newNotUsedAngleFromList.set(0, newNotUsedAngleFromList.get(newNotUsedAngleFromList.size()-1));
					newNotUsedAngleFromList.remove(newNotUsedAngleFromList.size()-1);
					newNotUsedAngleToList.remove(newNotUsedAngleToList.size()-1);
				}
			}
			if (newNotUsedAngleFromList.size()>0){
				notUsedAngleFromList.clear();
				notUsedAngleToList.clear();
				for (int i=0;i<newNotUsedAngleFromList.size();i++){
					notUsedAngleFromList.add(newNotUsedAngleFromList.get(i));
					notUsedAngleToList.add(newNotUsedAngleToList.get(i));
				}
			}
		}
	}
	
	
	
	@SuppressWarnings("unchecked")
	public void sumNotUsedAngle(){
		ArrayList<Double> newNotUsedAngleFromList = new ArrayList<Double>();
		ArrayList<Double> newNotUsedAngleToList = new ArrayList<Double>();
		if (notUsedAngleFromList.size()>0){
			Double min = notUsedAngleFromList.get(0);
			Double max = notUsedAngleToList.get(0);
			for (int i=1;i<notUsedAngleFromList.size();i++){
				//System.out.println(max+"    "+notUsedAngleFromList.get(i));
				//System.out.println(min+"    "+max);
				if ((max > notUsedAngleFromList.get(i)-0.00001)&&(max < notUsedAngleFromList.get(i)+0.00001)){
					//System.out.println("asdasfdafsdfsad");
					max = notUsedAngleToList.get(i);
					if (i == notUsedAngleFromList.size()-1){
						//System.out.println("!@#$%^&)*&^");
						if ((notUsedAngleFromList.get(0)+0.00001 > max) && (notUsedAngleFromList.get(0)-0.00001 < max)){
							//System.out.println("tego tamtego ");
							if (newNotUsedAngleFromList.size()==0){
								newNotUsedAngleFromList.add(min);
								newNotUsedAngleToList.add(max);
							}
							else{
								newNotUsedAngleFromList.set(0, min);
							}
						}
						else if ((notUsedAngleFromList.get(0)+0.00001 > 6.283185307-max) && (notUsedAngleFromList.get(0)-0.00001 < 6.283185307-max)){
							//System.out.println("tego tamtego 22222 ");
							if (newNotUsedAngleFromList.size()==0){
								newNotUsedAngleFromList.add(min);
								newNotUsedAngleToList.add(max);
							}
							else{
								newNotUsedAngleFromList.set(0, min);
							}
						}
						else{
							//System.out.println("tego tamtego 33333 ");
							//System.out.println(min+"    "+max);
							newNotUsedAngleFromList.add(min);
							newNotUsedAngleToList.add(max);
						}
					}
				}
				else{
					//System.out.println("123456768");
					if (i == notUsedAngleFromList.size()-1){
						//System.out.println("!@#$%^&)*&^");
						if ((notUsedAngleFromList.get(0)+0.00001 > max) && (notUsedAngleFromList.get(0)-0.00001 < max)){
							//System.out.println("tego tamtego ");
							if (newNotUsedAngleFromList.size()==0){
								newNotUsedAngleFromList.add(min);
								newNotUsedAngleToList.add(max);
							}
							else{
								newNotUsedAngleFromList.set(0, min);
							}
						}
						else if ((notUsedAngleFromList.get(0)+0.00001 > 6.283185307-max) && (notUsedAngleFromList.get(0)-0.00001 < 6.283185307-max)){
							//System.out.println("tego tamtego 22222 ");
							if (newNotUsedAngleFromList.size()==0){
								newNotUsedAngleFromList.add(min);
								newNotUsedAngleToList.add(max);
							}
							else{
								newNotUsedAngleFromList.set(0, min);
							}
						}
						else{
							newNotUsedAngleFromList.add(min);
							newNotUsedAngleToList.add(max);
						}
					}
					else{
						newNotUsedAngleFromList.add(min);
						newNotUsedAngleToList.add(max);
					}
					if (i<notUsedAngleFromList.size()-1){
						min = notUsedAngleFromList.get(i+1);
						max = notUsedAngleToList.get(i+1);
					}
				}
			}
			notUsedAngleFromList.clear();
			notUsedAngleToList.clear();
			if (newNotUsedAngleFromList.size()==0){
				newNotUsedAngleFromList.add(min);
				newNotUsedAngleToList.add(max);
			}
			for (int i=0;i<newNotUsedAngleFromList.size();i++){
				//System.out.println(i+"    "+newNotUsedAngleFromList.get(i)+"    "+newNotUsedAngleToList.get(i));
				notUsedAngleFromList.add(newNotUsedAngleFromList.get(i));
				notUsedAngleToList.add(newNotUsedAngleToList.get(i));
				//System.out.println(i+"    "+notUsedAngleFromList.get(i)+"    "+notUsedAngleToList.get(i));
			}
		}
	}
	
	public double maxDouble(double a, double b){
		if (a>b){
			return a;
		}
		return b;
	}
	
	public double minDouble(double a, double b){
		if (a<b){
			return a;
		}
		return b;
	}
	
	public boolean equalDouble(double a, double b){
		if ((a-0.00001<b)&&(a+0.00001>b)){
			return true;
		}
		return false;
	}
	
	public double countMiddleAngle(double middleAngle, double addAngle, int allocation){
		double _middle;
		if (maxDouble(middleAngle, addAngle) == addAngle){
			if (addAngle-middleAngle>3.1415926535){
				_middle = middleAngle * (allocation-1) + addAngle-6.283185307;
			}
			else{
				_middle = middleAngle * (allocation-1) + addAngle;
			}
		}
		else{
			if (middleAngle-addAngle>3.1415926535){
				_middle = middleAngle * (allocation-1) + addAngle+6.283185307;
			}
			else{
				_middle = middleAngle * (allocation-1) + addAngle;
			}
		}
		_middle = _middle/allocation;
		if (_middle>=6.283185307){
			_middle = _middle - 6.283185307;
		}
		return _middle;
	}
	
	public double intervalAngle(double angle){
		if (angle>6.283185307){
			return angle-6.283185307;
		}
		return angle;
	}
	
	//This code doesn't work correctly I comment it, an make easy version of this algorithm
	
	/*public ArrayList<Router> secondTypeStage(){
		double auxiliaryAngle;
		ArrayList<Router> returnRouterList = new ArrayList<Router>();
		for (int j=0;j<secondTypeRouter.size();j++){
			if (notUsedAngleFromList.size()>0){
				returnRouterList.add(secondTypeRouter.get(j));
				if (secondTypeAngleFromList.get(j)*secondTypeAngleToList.get(j)<0){
					auxiliaryAngle = (secondTypeAngleToList.get(j) + secondTypeAngleFromList.get(j)+6.283185307)/2;
				}
				else{
					auxiliaryAngle = (secondTypeAngleToList.get(j) + secondTypeAngleFromList.get(j))/2;
				}
				if (auxiliaryAngle<0){
					auxiliaryAngle = auxiliaryAngle + 6.283185307;
				}
				System.out.println("kąt wyszedł: "+auxiliaryAngle);
				for (int l=0;l<notUsedAngleFromList.size();l++){
					System.out.println("Ty to wiesz "+l+"  "+notUsedAngleFromList.get(l)+"  "+notUsedAngleToList.get(l));
					if (notUsedAngleFromList.get(l)<0){
						notUsedAngleFromList.set(l, notUsedAngleFromList.get(l)+6.283185307);
					}
					if (notUsedAngleToList.get(l)<0){
						notUsedAngleToList.set(l, notUsedAngleToList.get(l)+6.283185307);
					}
					if (notUsedAngleFromList.get(l)>notUsedAngleToList.get(l)){
						notUsedAngleToList.set(l, notUsedAngleToList.get(l)+6.283185307);
					}
					if ((notUsedAngleFromList.get(l)-0.00001<auxiliaryAngle)&&(notUsedAngleToList.get(l)+0.00001>auxiliaryAngle)){
						System.out.println("Znalazl");
						notUsedAngleFromList.add(l+1,intervalAngle(minDouble(notUsedAngleFromList.get(l),auxiliaryAngle-0.6)));
						notUsedAngleToList.add(l+1,intervalAngle(maxDouble(notUsedAngleFromList.get(l),auxiliaryAngle-0.6)));
						currentAngleFromList.add(intervalAngle(maxDouble(notUsedAngleFromList.get(l),auxiliaryAngle-0.6)));
						currentAngleToList.add(intervalAngle(minDouble(notUsedAngleToList.get(l),auxiliaryAngle+0.6)));
						notUsedAngleFromList.add(l+2,intervalAngle(minDouble(notUsedAngleFromList.get(l),auxiliaryAngle+0.6)));
						notUsedAngleToList.add(l+2,intervalAngle(maxDouble(notUsedAngleFromList.get(l),auxiliaryAngle+0.6)));
						notUsedAngleFromList.remove(l);
						notUsedAngleToList.remove(l);
						break;
					}
					else if ((notUsedAngleFromList.get(l)-0.00001<auxiliaryAngle+6.283185307)&&(notUsedAngleToList.get(l)+0.00001>auxiliaryAngle+6.283185307)){
						System.out.println("Znalazl");
						notUsedAngleFromList.add(l+1,intervalAngle(minDouble(notUsedAngleFromList.get(l),auxiliaryAngle+6.283185307-0.6)));
						notUsedAngleToList.add(l+1,intervalAngle(maxDouble(notUsedAngleFromList.get(l),auxiliaryAngle+6.283185307-0.6)));
						currentAngleFromList.add(intervalAngle(maxDouble(notUsedAngleFromList.get(l),auxiliaryAngle+6.283185307-0.6)));
						currentAngleToList.add(intervalAngle(minDouble(notUsedAngleToList.get(l),auxiliaryAngle+6.283185307+0.6)));
						notUsedAngleFromList.add(l+2,intervalAngle(minDouble(notUsedAngleFromList.get(l),auxiliaryAngle+6.283185307+0.6)));
						notUsedAngleToList.add(l+2,intervalAngle(maxDouble(notUsedAngleFromList.get(l),auxiliaryAngle+6.283185307+0.6)));
						notUsedAngleFromList.remove(l);
						notUsedAngleToList.remove(l);
						break;
					}
				}
			}
		}
		return returnRouterList;
	}
	
	public ArrayList<Router> lastStage(ArrayList<Router> previousIteration, 
			ArrayList<Router> inThisIteration, ArrayList<Integer> iterationRouter){
		ArrayList<Router> inThisIterationRouter = new ArrayList<Router>();
		ArrayList<Router> returnRouterList = new ArrayList<Router>();
		this.secondTypeAngleFromList.clear();
		this.secondTypeAngleToList.clear();
		this.secondTypeRouter.clear();
		this.secondTypeNeighbors.clear();
		this.secondTypeSum.clear();
		int k=0;
		Integer allocation=0;
		Integer secondSum;
		double middleAngleFrom;
		double middleAngleTo;
		double auxiliaryAngle;
		for (int i=0;i<previousIteration.size();i++){
			inThisIterationRouter.clear();
			k=0;
			while ((iterationRouter.size()>k) && (iterationRouter.get(k)<=i)){
				if (iterationRouter.get(k)==i){
					inThisIterationRouter.add(inThisIteration.get(k));
				}
				k++;
			}
			for (int j=0;j<inThisIterationRouter.size();j++){
				Router router = inThisIterationRouter.get(j);
				allocation = 0;
				middleAngleFrom = 0;
				middleAngleTo = 0;
				secondSum=0;
				for (int l=0;l<router.numberOfNeighbors;l++){
					Router router2 = router.connections.get(l).getNeighbor(router);
					if (router2.graphicsRouter.usedInAlg==true){
						allocation++;
						secondSum += router2.uniqeProgramNumber;
						if (allocation==1){
							middleAngleFrom = router2.graphicsRouter.angleFrom;
							middleAngleTo = router2.graphicsRouter.angleTo;
						}
						else{
							middleAngleFrom = countMiddleAngle(middleAngleFrom, router2.graphicsRouter.angleFrom, allocation);
							middleAngleTo = countMiddleAngle(middleAngleTo, router2.graphicsRouter.angleTo, allocation);
						}
					}
				}
				if (allocation >1){
					this.secondTypeRouter.add(router);
					this.secondTypeAngleFromList.add(middleAngleFrom);
					this.secondTypeAngleToList.add(middleAngleTo);
					this.secondTypeNeighbors.add(allocation);
					this.secondTypeSum.add(secondSum);
				}
			}
			for (int j=0;j<secondTypeRouter.size();j++){
				inThisIterationRouter.remove(secondTypeRouter.get(j));
			}
			if (inThisIterationRouter.size()>0){
				for (int j=0;j<inThisIterationRouter.size();j++){
					//System.out.println("pozycja "+j+" nazwa "+inThisIterationRouter.get(j).hostname);
				}
				inThisIterationRouter = sortList(inThisIterationRouter);
				for (int j=0;j<inThisIterationRouter.size();j++){
					//System.out.println("pozycja "+j+" nazwa "+inThisIterationRouter.get(j).hostname);
					returnRouterList.add(inThisIterationRouter.get(j));
				}
				auxiliaryAngle = (previousAngleToList.get(i)-previousAngleFromList.get(i))/inThisIterationRouter.size();
				for (int j=0;j<inThisIterationRouter.size();j++){
					currentAngleFromList.add(previousAngleFromList.get(i)+j*auxiliaryAngle);
					currentAngleToList.add(previousAngleFromList.get(i)+(j+1)*auxiliaryAngle);
				}
			}
			else{
				//System.out.println("iteracja "+i+" dane "+previousAngleFromList.get(i)+" "+previousAngleToList.get(i));
				if (notUsedAngleFromList.size()>0){
					for (int j=0;j<notUsedAngleFromList.size();j++){
						if (previousAngleFromList.get(i)<notUsedAngleFromList.get(j)){
							notUsedAngleFromList.add(j, previousAngleFromList.get(i));
							notUsedAngleToList.add(j, previousAngleToList.get(i));
							break;
						}
						if (j==(notUsedAngleFromList.size()-1)){
							notUsedAngleFromList.add(previousAngleFromList.get(i));
							notUsedAngleToList.add(previousAngleToList.get(i));
							break;
						}
					}
				}
				else{
					notUsedAngleFromList.add(previousAngleFromList.get(i));
					notUsedAngleToList.add(previousAngleToList.get(i));
				}
			}	
		}
		for (int i=0;i<notUsedAngleFromList.size();i++){
			System.out.println("NUALiteracja "+i+" dane "+notUsedAngleFromList.get(i)+" "+notUsedAngleToList.get(i));
		}
		sumNotUsedAngle2();
		for (int i=0;i<notUsedAngleFromList.size();i++){
			System.out.println("NUALiteracja "+i+" dane "+notUsedAngleFromList.get(i)+" "+notUsedAngleToList.get(i));
		}
		System.out.println("ile ich "+secondTypeRouter.size());
		int positionInTable;
		ArrayList<Router> r = new ArrayList<Router>();
		r = secondTypeStage();
		for (Router ro:r){
			returnRouterList.add(ro);
		}
		return returnRouterList;
	}*/
	
	public ArrayList<Router> lastStage(ArrayList<Router> previousIteration, 
			ArrayList<Router> inThisIteration, ArrayList<Integer> iterationRouter){
		ArrayList<Router> returnRouterList = new ArrayList<Router>();
		ArrayList<Router> forThisRouter = new ArrayList<Router>();
		double angle;
		for (int i=0;i<previousIteration.size();i++){
			for (int j=0;j<inThisIteration.size();j++){
				for (int l=0;l<inThisIteration.get(j).numberOfNeighbors;l++){
					if (previousIteration.get(i) == inThisIteration.get(j).connections.get(l).getNeighbor(inThisIteration.get(j))){
						forThisRouter.add(inThisIteration.get(j));
					}
				}
			}
			forThisRouter = sortList(forThisRouter);
			angle=this.previousAngleToList.get(i)-this.previousAngleFromList.get(i);
			angle=angle/forThisRouter.size();
			for (int j=0;j<forThisRouter.size();j++){
				inThisIteration.remove(forThisRouter.get(j));
				returnRouterList.add(forThisRouter.get(j));
				this.currentAngleFromList.add(this.previousAngleFromList.get(i)+j*angle);
				this.currentAngleToList.add(this.previousAngleFromList.get(i)+(j+1)*angle);
			}
			forThisRouter.clear();
		}
		return returnRouterList;
	}
	
	public void arrangeRouters(){
		ArrayList<GraphicsRouter> toArrange = new ArrayList<GraphicsRouter>();
		ArrayList<Router> minHopRouters = new ArrayList<Router>();
		ArrayList<Router> inThisIteration = new ArrayList<Router>();
		ArrayList<Router> previousIteration = new ArrayList<Router>();
		ArrayList<Integer> iterationRouter = new ArrayList<Integer>();
		previousAngleFromList = new ArrayList<Double>();
		previousAngleToList = new ArrayList<Double>();
		currentAngleFromList = new ArrayList<Double>();
		currentAngleToList = new ArrayList<Double>();
		secondTypeRouter = new ArrayList<Router>();
		notUsedAngleToList = new ArrayList<Double>();
		notUsedAngleFromList = new ArrayList<Double>();
		for (GraphicsRouter graphicsRouter:routerList.graphicsRouters){
			toArrange.add(graphicsRouter);
		}
		//int k=0;
		//int iter;
		double angle=0;
		//int allNeighbors=0;
		int middleX=132000;
		int middleY=96000;
		int radius;
		int auxiliaryX;
		int auxiliaryY;
		int minX=java.lang.Integer.MAX_VALUE;
		int minY=java.lang.Integer.MAX_VALUE;
		double auxiliaryAngle;
		//Router middleRouter = routerList.minAllHop();
		minHopRouters = routerList.minAllHop();
		if (minHopRouters.size()==1){
			iteration++;
			Router router = (Router) minHopRouters.get(0);
			toArrange.remove(router.graphicsRouter);
			router.graphicsRouter.usedInAlg = true;
			router.graphicsRouter.setPosition(middleX, middleY);
			radius = (router.numberOfNeighbors/6+1)*100;
			//System.out.println("Kątdfsdf "+router.numberOfNeighbors);
			if (router.numberOfNeighbors>1){
				angle=6.283185307/router.numberOfNeighbors;
				//System.out.println("Kąt "+angle);
			}
			
			for (int i=0;i<router.numberOfNeighbors;i++){
				Router router2 = router.connections.get(i).getNeighbor(router);
				inThisIteration.add(router2);
				toArrange.remove(router2.graphicsRouter);
				router2.graphicsRouter.usedInAlg = true;
			}
			inThisIteration = sortList(inThisIteration);
			
			for (int i=0;i<inThisIteration.size();i++){
				Router router2 = inThisIteration.get(i);
				auxiliaryAngle = i*angle-angle/2;
				/*if (auxiliaryAngle<0){
					auxiliaryAngle = 6.283185307-auxiliaryAngle;
				}*/
				previousAngleFromList.add(auxiliaryAngle);
				auxiliaryAngle = i*angle+angle/2;
				previousAngleToList.add(auxiliaryAngle);
				router2.graphicsRouter.setAngle(auxiliaryAngle-angle, auxiliaryAngle);
				auxiliaryX = (int)(middleX + Math.sin(angle*i)*radius);
				auxiliaryY = (int)(middleY - Math.cos(angle*i)*radius);
				if (minX>auxiliaryX){
					minX=auxiliaryX;
				}
				if (maxX<auxiliaryX){
					maxX=auxiliaryX;
				}
				if (minY>auxiliaryY){
					minY=auxiliaryY;
				}
				if (maxY<auxiliaryY){
					maxY=auxiliaryY;
				}
				//System.out.println("PozX "+auxiliaryX+" PozY "+auxiliaryY);
				router2.graphicsRouter.setPosition(auxiliaryX, auxiliaryY);
				previousIteration.add(router2);
			}
			inThisIteration.clear();
			while (toArrange.size()>0){
			//if (toArrange.size()>0){
				iteration++;
				//System.out.println("WHILE!!!");
				for (int i=0;i<previousIteration.size();i++){
					//System.out.println("Ile razy ten for"+previousIteration.get(i).hostname);
					router = (Router) previousIteration.get(i);
					for (int j=0;j<router.numberOfNeighbors;j++){
						Router router2 = router.connections.get(j).getNeighbor(router);
						if ((router2.graphicsRouter.usedInAlg == false)&&(router2.graphicsRouter.nowInAlg == false)){
							inThisIteration.add(router2);
							router2.graphicsRouter.nowInAlg = true;
							iterationRouter.add(i);
						}
					}
				}
				/*System.out.println("adasdasfsaF ");
				for (int i=0;i<previousIteration.size();i++){
					System.out.println("prev "+previousIteration.get(i).hostname);
				}
				for (int i=0;i<inThisIteration.size();i++){
					System.out.println("curr "+inThisIteration.get(i).hostname);
					System.out.println("iter "+iterationRouter.get(i));
				}*/
				
				inThisIteration=lastStage(previousIteration, inThisIteration, iterationRouter);
				radius +=140;
				previousIteration.clear();
				previousAngleFromList.clear();
				previousAngleToList.clear();
				System.out.println("jest ich "+inThisIteration.size());
				for (int i=0;i<inThisIteration.size();i++){
					Router router2 = inThisIteration.get(i);
					/*auxiliaryAngle = i*angle-angle/2;
					if (auxiliaryAngle<0){
						auxiliaryAngle = 6.283185307-auxiliaryAngle;
					}
					previousAngleFromList.add(auxiliaryAngle);
					auxiliaryAngle = i*angle+angle/2;
					previousAngleToList.add(auxiliaryAngle);*/
					//System.out.println("xa"+previousAngleFromList.get(i));
					//System.out.println("xb"+previousAngleToList.get(i));
					//System.out.println("xa"+currentAngleFromList.get(i));
					//System.out.println("xb"+currentAngleToList.get(i));
					angle = (currentAngleToList.get(i)+currentAngleFromList.get(i))/2;
					previousAngleFromList.add(currentAngleFromList.get(i));
					previousAngleToList.add(currentAngleToList.get(i));
					if (angle<0){
						angle = 6.283185307 + angle;
					}
					auxiliaryX = (int)(middleX + Math.sin(angle)*radius);
					auxiliaryY = (int)(middleY - Math.cos(angle)*radius);
					if (minX>auxiliaryX){
						minX=auxiliaryX;
					}
					if (maxX<auxiliaryX){
						maxX=auxiliaryX;
					}
					if (minY>auxiliaryY){
						minY=auxiliaryY;
					}
					if (maxY<auxiliaryY){
						maxY=auxiliaryY;
					}
					//System.out.println("PozXt "+auxiliaryX+" PozYt "+auxiliaryY);
					//System.out.println("Ruter "+router2.hostname);
					router2.graphicsRouter.setPosition(auxiliaryX, auxiliaryY);
					router2.graphicsRouter.usedInAlg = true;
					previousIteration.add(router2);
					toArrange.remove(router2.graphicsRouter);
				}
				for (int j=0;j<previousAngleFromList.size();j++){
					//System.out.println("poprzednie "+currentAngleFromList.get(j)+"  "+currentAngleToList.get(j));
					//System.out.println(j+"  poprzednie "+previousAngleFromList.get(j)+"  "+previousAngleToList.get(j));
				}
				inThisIteration.clear();
				iterationRouter.clear();
				currentAngleToList.clear();
				currentAngleFromList.clear();
			}	
		}
		else if (minHopRouters.size()>1){
			System.out.println("Kilka: ");
			for (Object o:minHopRouters){
				Router p = (Router) o;
				System.out.println(p.hostname);
			}
			//tu sie jazda zaczyna
				iteration++;
				
				for (Object o:minHopRouters){
					Router router = (Router) o;
					toArrange.remove(router.graphicsRouter);
					router.graphicsRouter.usedInAlg = true;
					inThisIteration.add(router);
				}
				
				radius = (inThisIteration.size()/6+1)*100;
				//System.out.println("Kątdfsdf "+router.numberOfNeighbors);
				if (inThisIteration.size()>1){
					angle=6.283185307/inThisIteration.size();
					//System.out.println("Kąt "+angle);
				}
				
				inThisIteration = sortList(inThisIteration);
				
				for (int i=0;i<inThisIteration.size();i++){
					Router router2 = inThisIteration.get(i);
					auxiliaryAngle = i*angle-angle/2;
					/*if (auxiliaryAngle<0){
						auxiliaryAngle = 6.283185307-auxiliaryAngle;
					}*/
					previousAngleFromList.add(auxiliaryAngle);
					auxiliaryAngle = i*angle+angle/2;
					previousAngleToList.add(auxiliaryAngle);
					router2.graphicsRouter.setAngle(auxiliaryAngle-angle, auxiliaryAngle);
					auxiliaryX = (int)(middleX + Math.sin(angle*i)*radius);
					auxiliaryY = (int)(middleY - Math.cos(angle*i)*radius);
					if (minX>auxiliaryX){
						minX=auxiliaryX;
					}
					if (maxX<auxiliaryX){
						maxX=auxiliaryX;
					}
					if (minY>auxiliaryY){
						minY=auxiliaryY;
					}
					if (maxY<auxiliaryY){
						maxY=auxiliaryY;
					}
					//System.out.println("PozX "+auxiliaryX+" PozY "+auxiliaryY);
					router2.graphicsRouter.setPosition(auxiliaryX, auxiliaryY);
					previousIteration.add(router2);
				}
				inThisIteration.clear();
				
				//odtąd jest już iteracja dobrze
				
				Router router;
				while (toArrange.size()>0){
				//if (toArrange.size()>0){
					iteration++;
					//System.out.println("WHILE!!!");
					for (int i=0;i<previousIteration.size();i++){
						//System.out.println("Ile razy ten for"+previousIteration.get(i).hostname);
						router = (Router) previousIteration.get(i);
						for (int j=0;j<router.numberOfNeighbors;j++){
							Router router2 = router.connections.get(j).getNeighbor(router);
							if ((router2.graphicsRouter.usedInAlg == false)&&(router2.graphicsRouter.nowInAlg == false)){
								inThisIteration.add(router2);
								router2.graphicsRouter.nowInAlg = true;
								iterationRouter.add(i);
							}
						}
					}
					/*System.out.println("adasdasfsaF ");
					for (int i=0;i<previousIteration.size();i++){
						System.out.println("prev "+previousIteration.get(i).hostname);
					}
					for (int i=0;i<inThisIteration.size();i++){
						System.out.println("curr "+inThisIteration.get(i).hostname);
						System.out.println("iter "+iterationRouter.get(i));
					}*/
					inThisIteration=lastStage(previousIteration, inThisIteration, iterationRouter);
					radius +=140;
					previousIteration.clear();
					previousAngleFromList.clear();
					previousAngleToList.clear();
					System.out.println("jest ich "+inThisIteration.size());
					for (int i=0;i<inThisIteration.size();i++){
						Router router2 = inThisIteration.get(i);
						/*auxiliaryAngle = i*angle-angle/2;
						if (auxiliaryAngle<0){
							auxiliaryAngle = 6.283185307-auxiliaryAngle;
						}
						previousAngleFromList.add(auxiliaryAngle);
						auxiliaryAngle = i*angle+angle/2;
						previousAngleToList.add(auxiliaryAngle);*/
						//System.out.println("xa"+previousAngleFromList.get(i));
						//System.out.println("xb"+previousAngleToList.get(i));
						//System.out.println("xa"+currentAngleFromList.get(i));
						//System.out.println("xb"+currentAngleToList.get(i));
						angle = (currentAngleToList.get(i)+currentAngleFromList.get(i))/2;
						previousAngleFromList.add(currentAngleFromList.get(i));
						previousAngleToList.add(currentAngleToList.get(i));
						if (angle<0){
							angle = 6.283185307 + angle;
						}
						auxiliaryX = (int)(middleX + Math.sin(angle)*radius);
						auxiliaryY = (int)(middleY - Math.cos(angle)*radius);
						if (minX>auxiliaryX){
							minX=auxiliaryX;
						}
						if (maxX<auxiliaryX){
							maxX=auxiliaryX;
						}
						if (minY>auxiliaryY){
							minY=auxiliaryY;
						}
						if (maxY<auxiliaryY){
							maxY=auxiliaryY;
						}
						//System.out.println("PozXt "+auxiliaryX+" PozYt "+auxiliaryY);
						//System.out.println("Ruter "+router2.hostname);
						router2.graphicsRouter.setPosition(auxiliaryX, auxiliaryY);
						router2.graphicsRouter.usedInAlg = true;
						previousIteration.add(router2);
						toArrange.remove(router2.graphicsRouter);
					}
					for (int j=0;j<previousAngleFromList.size();j++){
						//System.out.println("poprzednie "+currentAngleFromList.get(j)+"  "+currentAngleToList.get(j));
						//System.out.println(j+"  poprzednie "+previousAngleFromList.get(j)+"  "+previousAngleToList.get(j));
					}
					inThisIteration.clear();
					iterationRouter.clear();
					currentAngleToList.clear();
					currentAngleFromList.clear();
				}	
			
			//koniec misji
			
			
			
		}
		for (Object o:routerList.graphicsRouters){
			GraphicsRouter graphicsRouter = (GraphicsRouter) o;
			graphicsRouter.changePosition(minX, minY);
		}
		
		for (Object o:connectionList.graphicsConnections){
			GraphicsConnection cl=(GraphicsConnection) o;
			cl.setPosition();
		}
	}
	
	boolean grab=false;
	public void Refresh(){
		final PaintConnections pC=new PaintConnections(connectionList);
		pC.setSize(maxX, maxY);
		pC.repaint();
		
		for (Object gr: routerList.graphicsRouters){
			final GraphicsRouter rb=(GraphicsRouter) gr;
			final JLabel labelRouter = new JLabel();
			labelRouter.setIcon(picture);
			labelRouter.setBounds(rb.posX, rb.posY,picture.getIconWidth(),picture.getIconHeight());
			labelRouter.addMouseListener(new MouseAdapter() {
				int x;
				int y;
				@Override
				public void mousePressed(MouseEvent arg0){
					if (arg0.getClickCount()==2){
						if (grab==true){
							grab=false;
						}
						else{
							RouterWindow rw = new RouterWindow(rb);
							rw.getFrame().setVisible(true);
							grab=true;
						}
						System.out.println(2);
					}
					else{
						x=arg0.getX();
						y=arg0.getY();
					}
				}
				@Override
				public void mouseReleased(MouseEvent arg0){
					if ((arg0.getClickCount()==1)&&(grab==false)){
						if (maxX<rb.posX+arg0.getX()-x+100){
							maxX=rb.posX+arg0.getX()-x+100;
						}
						if (maxY<rb.posY+arg0.getY()-y+100){
							maxY=rb.posY+arg0.getY()-y+100;
						}
						pC.changeSize(maxX, maxY);
						pC.repaint();
						labelRouter.setLocation(rb.posX+arg0.getX()-x, rb.posY+arg0.getY()-y);
						rb.setPosition(rb.posX+arg0.getX()-x, rb.posY+arg0.getY()-y);
						
						for (Object o:connectionList.graphicsConnections){
							GraphicsConnection cl=(GraphicsConnection) o;
							cl.setPosition();
						}
					}
				}
			});
			add(labelRouter);
		}
		add(pC);
	}
	
	public GraphicsPanel() {
		this.connectionList = new ConnectionList();
		this.routerList = new RouterList(connectionList);
		setLayout(null);
		picture=new ImageIcon(GraphicsPanel.class.getResource("/edu/put/sk/nrpp/ui/resources/router icon.jpg"));
		img = picture.getImage().getScaledInstance(picture.getIconWidth()/4,picture.getIconHeight()/4, Image.SCALE_FAST);
		picture.setImage(img);
		Test test=new Test(routerList);
		if (routerList.routers.size()!=0){
			System.out.println("Zaczyna się Floyd");
			routerList.algorithmFloyd();
			System.out.println("Kończy się Floyd");
			for (int i=0;i<routerList.allHop.size();i++){
				System.out.println(routerList.routers.get(i).id);
				System.out.println(routerList.allHop.get(i));
			}
			arrangeRouters();
		}
		Refresh();
	}
	
}
